package com.fy.market.strategy.service.rule.chain.impl;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
import com.fy.market.strategy.model.entity.RuleChainResultEntity;
import com.fy.market.strategy.repository.IStrategyRepository;
import com.fy.market.strategy.service.rule.chain.AbstractLogicChain;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author fwq
 * @date 2025-09-18
 * @desc 责任链权重节点
 */
@Slf4j
@Service("rule_weight")
public class RuleWeightLogicChain extends AbstractLogicChain {
    @Resource
    private IStrategyRepository iStrategyRepository;
    /**
     * 权重过滤
     * @param userId 用户ID
     * @param strategyId 策略ID
     * @return 奖品ID
     */
    @Override
    public RuleChainResultEntity logic(Integer userId, Integer strategyId) {
        log.info("----- 开始执行权重过滤(前置) -----");
        // 查询该策略的【次数 -> 奖品ID集合】分组（如：0 -> [102,103], 4000 -> [102,103,104] ...）
        Map<Integer, List<Integer>> ruleWeightMap = iStrategyRepository.queryRuleWeightGroupByTimes(strategyId);
        if (MapUtil.isEmpty(ruleWeightMap)) {
            log.info("获取权重分组失败,交给下一个责任链节点");
            return next().logic(userId, strategyId);
        }
        // 获取用户抽奖次数（模拟，后续接入表查询）
        // 后续创建用户抽奖记录库表,存储统计的抽奖次数 TODO
        Integer userRaffleCount = 0; //模拟数据

        // 4. 找到匹配的 times 范围（最大 <= userRaffleCount 的 times）
        List<Integer> sortedTimes = new ArrayList<>(ruleWeightMap.keySet()).stream().sorted().collect(Collectors.toList());
        Integer matchedTimes = sortedTimes.stream()
                .filter(times -> times <= userRaffleCount)
                .max(Integer::compareTo).orElse(-1);

        // 8. 构建返回结果
        if (matchedTimes == -1) {
            log.info("获取权重抽奖桶失败,交给下一个责任链节点");
            return next().logic(userId, strategyId);
        }
        // 5. 构造 Redis key 并读取范围大小
        Integer rangeSize = iStrategyRepository.queryAllRate(strategyId, matchedTimes);

        // 6. 随机取序号（1 ~ rangeSize）
        Integer randomIndex = RandomUtil.randomInt(1,rangeSize+1);

        log.info("抽奖桶{}",matchedTimes);
        log.info("随机序号{}",randomIndex);
        // 7. 读取对应 Map 并取奖品 ID
        Integer awardId = iStrategyRepository.doRaffle(strategyId, matchedTimes, randomIndex);
        // 打印获取的奖品
        log.info("获取的奖品:{}",awardId);
        log.info("权重规则接管,获得奖品:{}", awardId);
        return RuleChainResultEntity.builder().awardId(awardId).strategyId(strategyId).build();
    }
}
